<template>
  <div class="opd-basic-table" @click.stop="activeMetaTo" :class="activeClass">
    <ATable :bordered="model.bordered" :pagination="model.pagination" :size="model.size"
            :columns="columns" rowKey="id" :showHeader="model.showHeader" :dataSource="data" style="flex-grow: 1">
      <template #action="{record}">
        <ATag v-for="meta in funcMetas" :key="meta.func" class="opd-table-func" color="#2db7f5">
          {{meta.name}}
        </ATag>
      </template>
    </ATable>
  </div>
</template>

<script>
import {reactive, ref} from "vue";
import {mapGetters, mapMutations} from "vuex";
import {EventBus, EventType, FunEventType, MetaEventType, MetaRemoveEvent, MountedEventType} from "@/event";
import Draggable from "@/utils/draggable";
import {htmlTableFieldTabMetas, htmlTableTabMetas} from "@/metas/HtmlTableMetas";
import MetaUtils from "@/utils/MetaUtils";
import IvzBasicTh from "@/components/table/IvzBasicTh.vue";
import {FuncMetasMap} from "@/components/OptionsMetaData";
import ActiveMetaMixin from "@/components/mixins/ActiveMetaMixin";
import Utils from "@/utils/basic.utils";

export default {
  name: "IvzBasicTable",
  mixins: [ActiveMetaMixin],
  components: {IvzBasicTh, Draggable},
  setup() {
    let data = ref([]);
    return {
      data,
      tableActions: {},
    }
  },
  computed: {
    ...mapGetters({
      meta: 'tableMeta',
      model: 'tableTabModel',
      tableMetas: 'tableMetas',
      funcMetas: 'tableFunMetas',
      searchFunMetas: 'searchFunMetas'
    }),
    columns() {
      return this.tableMetas.map(item => item.tabModel);
    }
  },
  created() {
    this.data.push({id: '1'});
    if(Utils.isBlank(this.meta['tabMetas'])) {
      this.setTableTabMetas(htmlTableTabMetas)
      this.updateTableColumnsMetas({id: 'action', tabMetas: htmlTableFieldTabMetas,
        tabModel: {field: 'action', title: '操作', dataIndex: 'action', slots: {customRender: 'action'}
          , customHeaderCell: this.customHeaderCell}});

      this.funcMetas.push({func: 'del', name: FuncMetasMap['del']});
      this.funcMetas.push({func: 'edit', name: FuncMetasMap['edit']});
    } else {
      this.meta['tabMetas'] = htmlTableTabMetas;
      this.tableMetas.map(item => item.tabModel['customHeaderCell'] = this.customHeaderCell);
    }

    EventBus.listener(MetaEventType.formAfterCreate, meta => {
      let viewTo = meta.tabModel['fieldView'];
      if(viewTo && viewTo.includes('table')) {
        EventBus.publish(EventType.toTable, meta)
      }
    });

    EventBus.listener(EventType.formTitle, ({val, id}) => {
      let meta = MetaUtils.getMetaById(this.tableMetas, id);
      if(meta) {
        meta['tabModel']['title'] = val;
      }
    });

    EventBus.listener(EventType.formField, ({val, id}) => {
      let meta = MetaUtils.getMetaById(this.tableMetas, id);
      if(meta) {
        meta['tabModel']['field'] = val;
      }
    });

    EventBus.listener(EventType.toTable, (meta) => {
      let {id, type, field, title} = meta['tabModel'];
      this.updateTableColumnsMetas({id, type, title, tabMetas: htmlTableFieldTabMetas
        , tabModel: reactive({dataIndex: id, field, title, customHeaderCell: this.customHeaderCell})})
    });

    EventBus.listener(MetaRemoveEvent.delEditMeta, meta => {
      this.removeTableColumnMeta(meta);
    });

    EventBus.listener(EventType.funViewTo, meta => {
      let index = MetaUtils.includeMetas(this.funMetas, meta.id);
      let model = meta['tabModel'];
      let action = this.tableActions[meta.id];
      if(model['funViewTo'] == 'search') {
        if(index > -1) {
          this.funMetas.splice(index, 1);
        }
        if(action) {
          delete this.tableActions[meta.id]
        }
      } else {
        if(index == -1) {
          let {id, type} = meta;
          this.funMetas.push({id, type, tabModel: model});
        }
        if(!action) {
          this.tableActions[meta.id] = meta.id;
        }
      }

      let length = Object.keys(this.tableActions).length;
      let columnIndex = MetaUtils.includeMetas(this.columns, 'action');
      if(length == 1 && columnIndex == -1) {
        this.tableMetas.splice(this.tableMetas.length, 0
            , {id: 'action', type: 'action', tabModel: {field: 'action', fixed: 'right', title: '操作', align: 'center', scopedSlots: {title: 'actiontitle'}}});
      } else if(length == 0){
        this.tableMetas.splice(columnIndex, 1);
      }
    });

    // 表格多选框
    EventBus.listener(EventType.funBatch, meta => {
      let filter = this.searchFunMetas.filter(item => item['tabModel']['batch']);
      let index = MetaUtils.includeMetas(this.columns, 'selection');
      if(filter.length > 0 && index == -1) {
        this.tableMetas.splice(0, 0, {id: 'selection', type: 'selection', tabModel: {fixed: 'left'}});
      } else if(filter.length == 0 && index > -1) {
        this.tableMetas.splice(0, 1);
      }
    });

    // 监听新增功能点事件
    EventBus.listener(FunEventType.addTableFunc, (value) => {
      let map = value.map(func => { return {func, name: FuncMetasMap[func]}});
      this.funcMetas.length = 0;
      this.funcMetas.push(...map)
    })
  },
  mounted() {
    EventBus.publish(MountedEventType.table, this);
  },
  methods: {
    ...mapMutations(['updateTableColumnsMetas', 'setTableTabMetas'
      , 'removeTableColumnMeta', 'switchActiveMetaTo']),
    close(meta) {
      let index = this.funcMetas.findIndex(item => item.id == meta.id);
      if(index > -1) {
        this.funcMetas.splice(index, 1);
      }
    },
    moveHandle(evt) {
      let drop = evt['relatedContext']['element'];
      let drag = evt['draggedContext']['element'];

      // if(drop['tabModel'].fixed != 'no') {
      //   return false;
      // }
      // if(drag['tabModel'].fixed != 'no') {
      //   return false;
      // }

      if(drop['type'] == 'selection' || drop['type'] == 'action') {
        return false;
      }
      if(drag['type'] == 'selection' || drag['type'] == 'action') {
        return false;
      }

      return true;
    },
    // 表头单击处理
    headerClick(column, e) {
      let meta = this.tableMetas.find(item => item.id == column.dataIndex);
      this.switchActiveMetaTo(meta);
      e.stopPropagation();
    },
    //表头双击处理
    headerDbClick(column, e) {
      if(column.dataIndex == 'action') {
        return;
      }
      let metaById = MetaUtils.getMetaById(this.editMetas, column.dataIndex);
      if(metaById) {
        this.switchActiveMetaTo(metaById)
        this.switchEditVisible(true);
      }
    },
    customHeaderCell(column) {
      return {class: 'ivz-obh-cell', onClick: (e) => this.headerClick(column, e), onDblclick: (e) => this.headerDbClick(column, e)}
    }
  }
}
</script>

<style>
.opd-basic-table {
  display: flex;
}
.opd-table-func {
  cursor: pointer;
}
.opd-basic-table .ivz-obh-cell {
  cursor: pointer;
}
</style>
